﻿using System;
using System.IO;
using System.Collections.Generic;

namespace JetBlack.IO
{
    internal class NetworkWriter : BinaryWriter
    {
        public NetworkWriter(Stream stream)
            : base(stream)
        {
        }

        public void Write(IDictionary<string, object> dictionary)
        {
            if (dictionary == null)
                Write(0);
            else
            {
                Write(dictionary.Count);

                foreach (KeyValuePair<string, object> keyValuePair in dictionary)
                    Write(keyValuePair);
            }
        }

        private void Write(KeyValuePair<string, object> keyValuePair)
        {
            Write(keyValuePair.Key);

            Type type = keyValuePair.Value.GetType();
            TypeCode typeCode = Type.GetTypeCode(type);
            Write((byte)typeCode);
            Write(Type.GetTypeCode(type), keyValuePair.Value);
        }

        private void Write(TypeCode typeCode, object value)
        {
            switch (typeCode)
            {
                case TypeCode.Boolean:
                    Write((Boolean)value);
                    break;
                case TypeCode.Byte:
                    Write((Byte)value);
                    break;
                case TypeCode.Char:
                    Write((Char)value);
                    break;
                case TypeCode.DateTime:
                    Write((Int64)value);
                    break;
                case TypeCode.DBNull:
                    break;
                //case TypeCode.Decimal:
                //    writer.Write((Decimal)value);
                //    break;
                case TypeCode.Double:
                    Write((Double)value);
                    break;
                case TypeCode.Empty:
                    break;
                case TypeCode.Int16:
                    Write((Int16)value);
                    break;
                case TypeCode.Int32:
                    Write((Int32)value);
                    break;
                case TypeCode.Int64:
                    Write((Int64)value);
                    break;
                case TypeCode.SByte:
                    Write((SByte)value);
                    break;
                case TypeCode.Single:
                    Write((Single)value);
                    break;
                case TypeCode.String:
                    Write((String)value);
                    break;
                case TypeCode.UInt16:
                    Write((UInt16)value);
                    break;
                case TypeCode.UInt32:
                    Write((UInt32)value);
                    break;
                case TypeCode.UInt64:
                    Write((UInt64)value);
                    break;
                case TypeCode.Object:
                default:
                    throw new InvalidDataException("unsupported field type");
            }
        }
    }
}
